#include <sstream>
#include "SymbolsTable.h"

SymbolTable::SymbolTable() { }

SymbolTable::~SymbolTable() {
	// assumes responsibility for deleting IdentifierProperties
	for(HashMap::iterator i=symTable.begin();
		i!=symTable.end();
		++i)
	{
		delete(i->second);
	}
	symTable.clear();
}

bool SymbolTable::search(Token &tk) {
	TableEntry* dummy;
	return search(tk, dummy);
}

bool SymbolTable::search(Token &tk, TableEntry* &propPtr) {
	if(tk==TK_IDENTIFIER) 
	{
		return search(tk.getValue(), propPtr);
	} 
	else if (tk==TK_MAIN) 
	{
		return search("main", propPtr);
	}
	return false;
}

bool SymbolTable::search(std::string identifier, TableEntry* &propPtr) {
	HashMap::iterator i = symTable.find(identifier);
	if(i != symTable.end()) {
		propPtr = i->second;
		return true;
	} 
	return false;
}

void SymbolTable::insert(std::string identifier, TableEntry* propPtr) {
	propPtr->setName(identifier);
	
	HashMapPair temp(identifier, propPtr);
	symTable.insert( temp );
}

void SymbolTable::insert(Token &token, TableEntry* tabEntry) {
	if(token==TK_IDENTIFIER) 
	{
		insert(token.getValue(), tabEntry);
	}
	else if(token==TK_MAIN)
	{
		insert("main", tabEntry);
	}
}

std::ostream& SymbolTable::inserter(std::ostream &os) const {
	for(HashMap::const_iterator i=symTable.begin();
		i!=symTable.end();
		++i) 
	{
		os << i->first << " : " << *(i->second) << "\n";
	}

	return os;
}
